package edu.fyvtc.javaweb.demo.db;

import edu.fyvtc.javaweb.demo.model.House;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;

import java.util.*;

public class DBUtils {

    //定义一个House链表，用于存储House，模拟数据库
    private static final List<House> houseList = new LinkedList<>();

    //模拟数据插入操作
    public static int insert(House house) {
        //没有id，不允许插入，直接返回插入行数为0
        if (house.getId() == null) {
            return 0;
        }
        //设置一些属性，后续代码中要求这些属性非空
        if (house.getArea() == null) {
            house.setArea(50 + Math.floor(Math.random() * 100));
        }
        if (house.getCreateDate() == null) {
            house.setCreateDate(new Date());
        }
        if (house.getModifyDate() == null) {
            house.setModifyDate(house.getCreateDate());
        }

//        //首先流式遍历列表，查询出与待插入元素有相同id的元素列表
//        List<House> existList = houseList.stream().filter(
//                houseExist -> houseExist.getId().equals(house.getId())
//        ).toList();


//        //循环列表，依次比较，把与传入的id相同的house放入existList列表
//        //与上一段注释掉的代码功能相同，只是更为繁琐
//        List<House> existList = new LinkedList<>();
//        for (House existHouse : houseList) {
//            if (existHouse.getId().equals(house.getId())) {
//                existList.add(existHouse);
//            }
//        }


        //循环列表，依次比较，把与传入的id相同的house放入existList列表
        //与上一段注释掉的代码功能相同，只是更为繁琐
        List<House> existList = new LinkedList<>();
        for (int i = 0;i < houseList.size();i++) {
            House existHouse = houseList.get(i);
            if (existHouse.getId().equals(house.getId())) {
                existList.add(existHouse);
            }
        }


        //如果列表不为空，则说明元素已经存在，返回0，否则插入传入的元素，返回1
        if (CollectionUtils.isEmpty(existList)) {
            houseList.add(house);
            return 1;
        } else {
            return 0;
        }
    }

    //模拟查询操作，根据id查询相应的数据并返回，没查到则返回null
    public static House select(String id) {
        //链表的遍历，用法：for (链表元素类型 链表元素（名称自取） : 链表对象) {对链表元素的操作}
        for (House house : houseList) {
            if (house.getId().equals(id)) {
                return house;
            }
        }
        return null;
    }

    //模拟更新操作
    public static void update(House house) {
        //设置一些属性，后续代码中要求这些属性非空
        if (house.getArea() == null) {
            house.setArea(50 + Math.floor(Math.random() * 100));
        }
        if (house.getCreateDate() == null) {
            house.setCreateDate(new Date());
        }
        if (house.getModifyDate() == null) {
            house.setModifyDate(house.getCreateDate());
        }
        //链表的遍历，用法：链表对象.forEach(链表元素（名称自取）-> {对链表元素的操作})
        houseList.forEach(houseExist -> {
            if (houseExist.getId().equals(house.getId())) {
                //属性拷贝，将house复制给houseExist
                BeanUtils.copyProperties(house, houseExist);
            }
        });
    }

    //模拟删除操作，根据id查询相应的数据并删除、返回1，表示影响的行数。如果没查到则返回0
    public static int delete(String id) {
        //链表的遍历，首先返回链表的迭代器
        Iterator<House> iterator = houseList.iterator();
        //查询迭代器是否有下一个元素，如果迭代器有下一个元素，则进入循环
        while (iterator.hasNext()) {
            //获取下一个元素
            House house = iterator.next();
            if (house.getId().equals(id)) {
                //在迭代器中删除，则链表中对应的元素也会被删除
                iterator.remove();
                return 1;
            }
        }
        return 0;
    }

    //实现一个更为复杂的查询操作
    //查询area属性值大于给定值的House列表，按修改时间倒序排列
    public static List<House> query(Double area) {
        //新建一个链表resultList，用于存放符合条件的house
        List<House> resultList = new LinkedList<>();
        //如果area为空，直接返回一个空列表
        if (area == null) {
            return resultList;
        }
        //遍历已经存在的houseList，把符合条件的house插入到resultList中
        for (House house : houseList) {
            if (house.getArea() > area) {
                resultList.add(house);
            }
        }

        //对符合条件的列表排序，排序算法已经实现，默认升序排列，只需要定义一个比较器即可
        //比较器有一个compare方法，用于比较两个元素的大小，返回值为-1，0，1
        //返回-1代表o1小于o2，返回0代表o1等于o2，返回1代表o1大于o2
//        resultList.sort(new Comparator<House>() {
//            @Override
//            public int compare(House o1, House o2) {
//                if (o1.getModifyDate().before(o2.getModifyDate())) {
//                    return 1;
//                } else if (o1.getModifyDate().after(o2.getModifyDate())) {
//                    return -1;
//                } else {
//                    return 0;
//                }
//            }
//        });

//        //与上一段注释掉的代码功能相同，只是代码更为简洁
//        resultList.sort((o1, o2) -> {
//            if (o1.getModifyDate().before(o2.getModifyDate())) {
//                return 1;
//            } else if (o1.getModifyDate().after(o2.getModifyDate())) {
//                return -1;
//            } else {
//                return 0;
//            }
//        });


        //与上一段注释掉的代码功能相同，只是代码更为简洁
        resultList.sort(Comparator.comparing(House::getModifyDate).reversed());

        return resultList;
    }

}
